//
//  ZLShipVCManger.m
//  zhilian
//
//  Created by 张奇 on 2021/3/12.
//  Copyright © 2021 LZT. All rights reserved.
//

#import "ZLShipVCManger.h"
#import <objc/runtime.h>
//#import "BDNovelEntrance.h"
//#import "BDNovelPublicConfig.h"
//#import "LZTGuangGuangAPIRequest.h"
//#import "WXApi.h"


@interface ZLShipVCManger()

@property (nonatomic, strong) NSDictionary *allShipResource;

@end

@implementation ZLShipVCManger

+(ZLShipVCManger *)shareInstance {
    static ZLShipVCManger *model = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        model = [[self alloc] init];
    });
    return model;
}

/*
 @param shipUrl 跳转的路由地址
 返回值 是否配置过该路由：YES,可直接使用新的路由跳转; NO，表示未配置或需要使用旧的路由跳转
 */
+ (BOOL)isHavingConfigShipUrl:(NSString *)shipUrl {
    //获取当前路由的配置的信息
    NSDictionary *resultDic = [self getShipConfigwithUrl:shipUrl];
    return resultDic !=nil ? YES: NO;
}

/*
 @param navtive 跳转的url：@"zl://shop/goods?_id=5fe97ec9d1b2b7465187f260&uid=1";
 */
+ (void)pushNavtive:(NSString *)navtive {
    [self pushNavtive:navtive rootViewController:nil extrasParams:nil finishCallBack:nil];
}

/*
 @param navtive 跳转的url：@"zl://shop/goods?_id=5fe97ec9d1b2b7465187f260&uid=1";
 @param rootVC  默认nil.
 */
+ (void)pushNavtive:(NSString *)navtive
 rootViewController:(UINavigationController* _Nullable)rootVC {
    [self pushNavtive:navtive rootViewController:rootVC extrasParams:nil finishCallBack:nil];
}

/*
 @param navtive 跳转的url：@"zl://shop/goods?_id=5fe97ec9d1b2b7465187f260&uid=1";
 @param extrasParams    额外参数，一般用来传递对象，导航栏状态，页面状态等，默认nil.
 */
+ (void)pushNavtive:(NSString *)navtive
       extrasParams:(NSDictionary * _Nullable)extrasParams {
    [self pushNavtive:navtive rootViewController:nil extrasParams:extrasParams finishCallBack:nil];
}

/*
 @param navtive 跳转的url：@"zl://shop/goods?_id=5fe97ec9d1b2b7465187f260&uid=1";
 @param extrasParams    额外参数，一般用来传递对象，导航栏状态，页面状态等，默认nil.
 @param callBack 被弹出控制器需要回调的block
 */
+ (void)pushNavtive:(NSString *)navtive
       extrasParams:(NSDictionary * _Nullable)extrasParams
 rootViewController:(UINavigationController* _Nullable)rootVC {
    [self pushNavtive:navtive rootViewController:nil extrasParams:extrasParams finishCallBack:nil];
}

/*
 @param navtive   跳转的url：@"zl://shop/goods?_id=5fe97ec9d1b2b7465187f260&uid=1";
 @param rootVC
 @param extrasParams    额外参数，一般用来传递对象，导航栏状态，页面状态等，默认nil.
 @param callBack  被弹出控制器需要回调的block, 使用回调block时，runtime给被弹出控制器赋值的默认block名称为callBack
                  如果回调的名字为myCallBack,则需要在plist中该路径对应的convertKeys中配置"callBack": "myCallBack"
 */
+ (void)pushNavtive:(NSString *)navtive
 rootViewController:(UINavigationController* _Nullable)rootVC
       extrasParams:(NSDictionary * _Nullable)extrasParams
     finishCallBack:(ShipeFinishCallback _Nullable)callBack {
    if (rootVC== nil) {
        rootVC = [self getShipNavgation];
    }
    if ([TG_Vaildate isEmptyString:navtive]) {
        [TGProgressHUD showHUDTip:@"跳转链接不存在"];
        return;
    }
    //0.判断是否是跳转H5
    if ([TG_Vaildate isURLPrefix:navtive]) {
        [TGProgressHUD showHUDTip:@"跳转链接不存在"];
//        [LZTShipVCManager pushURL:navtive title:nil rootViewController:rootVC];
        return;
    }
//    else if (![navtive hasPrefix:@"zl://"])
    else if (![navtive hasPrefix:RoutingPrefix])
    {
        [TGProgressHUD showHUDTip:@"跳转链接配置错误"];
        return;
    }
    //1.整理参数
    NSMutableDictionary *params = [NSMutableDictionary dictionary];
    if (callBack != nil) {
        [params setObject:callBack forKey:@"callBack"];
    }
    //获取当前路由的配置的信息
    NSDictionary *resultDic = [self getShipConfigwithUrl:navtive];
    if(resultDic ==nil)
    {
        [TGProgressHUD showHUDTip:@"将要跳转的路径未设置在plist文件中"];
        return;
    }
    NSAssert(resultDic != nil, @"将要跳转的路径未设置在plist文件中!");
    //跳转进入的控制器名称，必须配置
    NSString *vcNameStr = [resultDic objectForKey:@"controller"];
    NSString *vcDesc = [resultDic objectForKey:@"desc"];
    if(vcNameStr ==nil)
    {
        [TGProgressHUD showHUDTip:@"控制器的名称未在plist中设置"];
        return;
    }
    NSAssert(vcNameStr != nil, @"控制器的名称未在plist中设置");
    if(vcDesc ==nil)
    {
        [TGProgressHUD showHUDTip:@"控制器的注释未在plist中设置"];
        return;
    }
    NSAssert(vcDesc != nil, @"控制器的注释未在plist中设置");
    //需要转换的key，可选，服务器key与控制器key不同时配置
    NSMutableDictionary *convertKeyMDic = [NSMutableDictionary dictionaryWithDictionary:resultDic[@"convertKeys"]];
    //添加额外的参数
    NSDictionary *extrasDic = resultDic[@"extras"];
    [params setValuesForKeysWithDictionary:extrasDic];
    [params setValuesForKeysWithDictionary:extrasParams];
    //添加url自带参数
//    [params setValuesForKeysWithDictionary:[navtive parseURLParameters]];
    NSDictionary *dic = [self queryItems:[NSURL URLWithString:navtive]];
    NSLog(@"url自带参数==%@", dic);
    [params setValuesForKeysWithDictionary:dic];

    NSLog(@"\n      ************************************************\n      **             %@\n      **                                          \n      **       vc= %@\n      **                                          \n      **       params:%@\n      **                                          \n      ************************************************\n    ", vcDesc, vcNameStr, params.toString);
    
    //2.跳转页面是要进行的特殊操作
//    if ([vcNameStr isEqualToString:@"O2OVouchersBuyController"]) {
//        LZTGlobalSharedInstance.isFirstLogin = YES;
//    }
    
    //3.动态生成控制器，并传递参数，跳转页面
    const char *className = [vcNameStr cStringUsingEncoding:NSASCIIStringEncoding];
    // 根据字符串返回一个类
    Class newClass = objc_getClass(className);
    if (!newClass) {
        // 创建一个类
        Class superClass = [NSObject class];
        newClass = objc_allocateClassPair(superClass, className, 0);
        // 注册你创建的这个类
        objc_registerClassPair(newClass);
    }
    // 创建对象（就是控制器对象）
    id instance = [[newClass alloc] init];
    [params enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
        //转换一下后台给的参数key名称
        if ([convertKeyMDic.allKeys containsObject:key]) {
            key = [convertKeyMDic objectForKey:key];
        }
        
        // 检测这个对象是否存在该属性
        if ([self checkIsExistPropertyWithInstance:instance verifyPropertyName:key]) {
            // 利用 KVC 对控制器对象的属性赋值
            [instance setValue:obj forKey:key];
        }
    }];
    NSLog(@"resultParams %@", params);
    
    [rootVC pushViewController:instance animated:YES];
   

//    NSString *needLogin = [params objectForKey:@"isNeedLogin"];
//    NSString *isPresent = [params objectForKey:@"isPresent"];
//    if ([@"1" isEqualToString:needLogin]) {
//        [LZT_Global isLoginComplent:^{
//            if ([@"1" isEqualToString:isPresent]) {
//                [rootVC presentViewController:instance animated:YES completion:nil];
//            } else {
//                [rootVC pushViewController:instance animated:YES];
//            }
//        }];
//    } else {
//        if ([@"1" isEqualToString:isPresent]) {
//            [rootVC presentViewController:instance animated:YES completion:nil];
//        } else {
//            [rootVC pushViewController:instance animated:YES];
//        }
//    }
    
}

//路径解析成字典
+ (NSDictionary<NSString *, NSString *> *)queryItems:(NSURL*)url{
    if (!url.absoluteString.length) {
        return nil;
    }
    NSMutableDictionary *params = [[NSMutableDictionary alloc] init];
    NSURLComponents *urlComponents = [[NSURLComponents alloc] initWithString:url.absoluteString];
    
    [urlComponents.queryItems enumerateObjectsUsingBlock:^(NSURLQueryItem * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        if (obj.name) {
            [params setObject:obj.value ?: [NSNull null] forKey:obj.name];
        }
    }];
    return [params copy];
}

// 检测对象是否存在该属性
+ (BOOL)checkIsExistPropertyWithInstance:(id)instance verifyPropertyName:(NSString *)verifyPropertyName {
   
    __block BOOL isHave = NO;

    [self qmui_enumratePropertiesOfClass:[instance class]
                      includingInherited:YES
                              usingBlock:^(objc_property_t  _Nonnull property, NSString * _Nonnull propertyName) {
        
        if ([propertyName isEqualToString:verifyPropertyName])
        {
            NSLog(@"propertyName===%@",propertyName);
            isHave = YES;
            return;
        }
    }];
    
    return isHave;

    
//    unsigned int count, i;
//
//   // 获取对象里的属性列表
//   objc_property_t *properties = class_copyPropertyList([instance class], &count);
//
//   for (i = 0; i < count; i++) {
//       objc_property_t property =properties[i];
//       //  属性名转成字符串
//       NSString *propertyName = [[NSString alloc] initWithCString:property_getName(property) encoding:NSUTF8StringEncoding];
//       NSLog(@"propertyName===%@",propertyName);
//       // 判断该属性是否存在
//       if ([propertyName isEqualToString:verifyPropertyName]) {
//           free(properties);
//           return YES;
//       }
//   }
//   free(properties);
//
//   return NO;
    
}

//根据路由连接获取配置数据
+ (NSDictionary *)getShipConfigwithUrl:(NSString *)shipUrl {
    //当前路由里面的路径转换的数组，例如o2o/store/detail -> @[@"o2o", @"store", @"detail"]
    NSArray *paths = [self getPathArrayFromUrl:shipUrl];
    //在plist中配置的路由资源
    NSDictionary *shipConfig = [self getShipResource];
    return [self getVCFromConfigDic:shipConfig pathArray:paths index:0];
}

//根据层数index和路径pathArray递归获取已配置的数据
+ (NSDictionary *)getVCFromConfigDic:(NSDictionary *)dic pathArray:(NSArray *)pathArray index:(NSInteger)index {
    NSDictionary *tempDic = [dic objectForKey:pathArray[index]];
   if (tempDic == nil) {
       return nil;
   } else if ([tempDic.allKeys containsObject:@"controller"]) {
//        NSLog(@"tempDic%@", tempDic);
        return tempDic;
    } else {
        index++;
        return [self getVCFromConfigDic:tempDic pathArray:pathArray index:index];
    }
}

//将完整的路由转换为数组  @"zl://o2o/vouchersBuy?storeId=%@&selectId=%@"
+ (NSArray *)getPathArrayFromUrl:(NSString *)url {
    NSRange range = [url rangeOfString:@"?"];
    NSRange contentRange = [url rangeOfString:@"//"];
    NSString *path;
    if (contentRange.location == NSNotFound) {
        //后台url配置错误
        path = @"";
    } else if (range.location == NSNotFound) {
        path = [url substringFromIndex:contentRange.location+2];
    } else {
        path = [[url substringToIndex:range.location] substringFromIndex:contentRange.location+2];
    }
    return [path componentsSeparatedByString:@"/"];
}

//获取本地的plist配置数据
+ (NSDictionary *)getShipResource {
    if (!ZLShipVCManger.shareInstance.allShipResource) {
        NSString * path = [[NSBundle mainBundle] pathForResource:@"shipConfig" ofType:@"plist"];
        NSDictionary *plistResource = [NSDictionary dictionaryWithContentsOfFile:path];
        NSLog(@"plistResource:----- %@", plistResource);
//        NSDictionary *shipResource = plistResource[@"zl://"];
        NSDictionary *shipResource = plistResource[RoutingPrefix];
        ZLShipVCManger.shareInstance.allShipResource = shipResource;
    }
    return ZLShipVCManger.shareInstance.allShipResource;
}

+ (UINavigationController *)getShipNavgation {
    UINavigationController *rootVC = nil;
    if (rootVC==nil) {
        rootVC = [self getNewCurrentVC].navigationController;
    }
    if (rootVC == nil || ![rootVC isKindOfClass:[UINavigationController class]]) {
        rootVC = [self getNavigationVC];
    }
    return rootVC;
}

/*
 /// 获取当天阅读时长，单位秒
 */
//+ (NSUInteger)getReadDuration {
//    return [BDNovelPublicConfig getReadDuration] * 1000;
//}
//+ (void)zlPushNovel{
//    UIViewController *channel = [BDNovelPublicConfig novelViewControllerWithType:BDNovelPublicEnTranceTypeChannelPage userInfo:nil];
//    UINavigationController *nav= [[UINavigationController alloc] initWithRootViewController:channel];
//    nav.fd_viewControllerBasedNavigationBarAppearanceEnabled = NO;
//    channel.fd_prefersNavigationBarHidden = YES;
//    nav.modalPresentationStyle = UIModalPresentationFullScreen;
//    [[LZTShipVCManager shareInstance].getNewCurrentVC presentViewController:nav animated:YES completion:^{
//    }];
//}

/*

/// 根据后台跳转配置跳转至相关页面
/// @param iconId 图标id
/// @param jumpConfig 模型 根据内部actionType 跳转优先级 0:原生地址 1:小程序地址 2:H5地址
/// @param showHUDInView 加载图
+ (void)pushActionWithIconId:(NSString *)iconId
                  jumpConfig:(ZGHomeIconJumpConfigModel *)jumpConfig
               showHUDInView:(UIView *)showHUDInView {
    if (jumpConfig.loginAccess) {
        //1.需要登录后跳转
        [LZT_Global isLoginComplent:^{
            [self beginPushWithIconId:iconId jumpConfig:jumpConfig showHUDInView:showHUDInView];
        }];
    } else {
        [self beginPushWithIconId:iconId jumpConfig:jumpConfig showHUDInView:showHUDInView];
    }
}

//2.开始跳转判断
+ (void)beginPushWithIconId:(NSString *)iconId
                 jumpConfig:(ZGHomeIconJumpConfigModel *)jumpConfig
              showHUDInView:(UIView *)showHUDInView {
    NSDictionary *params = [jumpConfig.lztUrl parseURLParameters];
    //手动给这两个字段赋值
    jumpConfig.iconId = R(iconId);
    jumpConfig.actId = R(params[@"actId"]?:params[@"actid"]);
    
    if (!jumpConfig.convertShortLinkFlag) {
        //actionType 跳转优先级 0:原生地址 1:小程序地址 2:H5地址
        NSArray *actionType = jumpConfig.actionType;
        for (int i=0; i<actionType.count; i++) {
            NSString *type = [NSString stringWithFormat:@"%@", actionType[i]];
            if (![self getIsNeedNextForPushAction:type jumpModel:jumpConfig]) {
                return;
            }
        }
        return;
    }
    
    [LDProgressHUD showHUD:nil view:showHUDInView];
    
    [LZTGuangGuangAPIRequest GETIconInfoRedirectWithId:iconId actId:R(params[@"actId"]?:params[@"actid"]) configId:R(jumpConfig._id) success:^(id response) {
        [LDProgressHUD dismissMPHUD];
        BaseModel *baseModel = [BaseModel ld_modelWithJSON:response];
        if ([baseModel isSuccess]) {
            ZGHomeIconJumpConfigModel *jumpConfig = [ZGHomeIconJumpConfigModel yy_modelWithJSON:response[@"data"]];
            jumpConfig.iconId = R(iconId);
            jumpConfig.actId = R(params[@"actId"]?:params[@"actid"]);
            //actionType 跳转优先级 0:原生地址 1:小程序地址 2:H5地址
            NSArray *actionType = jumpConfig.actionType;
            for (int i=0; i<actionType.count; i++) {
                NSString *type = [NSString stringWithFormat:@"%@", actionType[i]];
                if (![self getIsNeedNextForPushAction:type jumpModel:jumpConfig]) {
                    return;
                }
            }

        }
    } fail:^(NSError *error) {
        [LDProgressHUD dismissMPHUD];
    }];
}

//3.是否需要检查下一个跳转配置，NO表示跳转配置符合跳转逻辑，可直接跳转； YES表示继续检查下一个跳转配置
+ (BOOL)getIsNeedNextForPushAction:(NSString *)actionType
                         jumpModel:(ZGHomeIconJumpConfigModel *)jumpModel {
    if ([@"0" isEqualToString:actionType] && !EmptyCheck(jumpModel.lztUrl)
        && ![jumpModel.lztUrl isEqualToString:@"fake_data"]) {
        if (jumpModel.electricFeeIconFlag) {
            return YES;
        } else {
            [LZTShipVCManager pushAction:jumpModel.lztUrl rootViewController:nil];
            return NO;
        }
    } else if ([@"1" isEqualToString:actionType]) {
        if (EmptyCheck(jumpModel.actionMiniProgram) || ![WXApi isWXAppInstalled]
            || [jumpModel.actionMiniProgram isEqualToString:@"fake_data"]) {
            //没有小程序地址或者没安装微信或者跳转链接为空，下一个
            return YES;
        } else {
            [LZTShipVCManager pushAction:jumpModel.actionMiniProgram rootViewController:nil];
            return NO;
        }
    } else if ([@"2" isEqualToString:actionType] && !EmptyCheck(jumpModel.realH5Url)
               && ![jumpModel.realH5Url isEqualToString:@"fake_data"]) {
        [LZTShipVCManager pushAction:jumpModel.realH5Url rootViewController:nil];
        return NO;
    } else {
        return YES;
    }
}
 */

@end
